503 words
从1.0到3.0的性能革命HTTP/1.0(1996) 短连接模式:每次请求需新建TCP连接,如同每次点餐都要重新排队 基础功能框架:GET/POST/HEAD方法、状态码、首部字段奠定标准 性能痛点:加载含10张图片的网页需建立11次连接(1个HTML+10个图片) 123# 典型HTTP/1.0请求示例GET /index.html HTTP/1.0User-Agent: Mozilla/5.0 HTTP/1.1(1999) 长连接机制:Connection: keep-alive 实现TCP连接复用 管道化传输:允许连续发送多个请求(但响应必须按序返回) 关键创新: Host头支持虚拟主机 分块传输编码 缓存控制机制 队头阻塞问题:如同高速公路上的抛锚车辆,前一个未完成的请求会阻塞后续所有请求 HTTP/2(2015) 二进制分帧层:将消息分解为独立帧传输 多路复用技术:在单个连接上并行交错传输多个请求/响应 头部压缩:HPACK算法减少重复头部数据 服务器推送:主动推送CSS/JS等依赖资...
1.5k words
C++ CRTP 详解:奇异递归模板模式的原理与应用在 C++ 编程中,模板不仅仅用于泛型编程,还可以发挥出“元编程”的威力。CRTP,即“奇异递归模板模式”,正是一种利用模板实现静态多态和代码复用的设计模式。本文将从原理、示例、优缺点以及新标准对其的改进等多个角度详细讲解 CRTP。 CRTP 简介CRTP 的英文全称为 _Curiously Recurring Template Pattern_,顾名思义,就是让一个类在继承时将自身作为模板参数传给其基类。例如: 123456789101112131415161718192021// 基类模板template <typename Derived>class Base {public: // 调用派生类的成员函数 implementation() void interface() { static_cast<Derived*>(this)->implementation(); } // 如果派生类没有重写,基类可以提供一个默认实现...
2.3k words
本地的gitgit除了最经典的add commit push用来做版本管理,其实他的分支管理也非常强大 可以说你学好了分支管理,就可以完成团队的配合协作了 git仓库我们可以使用git init来初始化一个git仓库,只要能看见.git文件夹,就代表这是一个git仓库了 git分区git一共有三个分区,工作区、暂存区、版本库 工作区和.git文件夹在相同目录即为工作区,也就是我们写代码的地方 暂存区与版本库这两个分区实际上是存在.git文件夹里的 当我们使用add之后,代码就会被存储在暂存区,只有commit之后,也就是提交代码,整个代码才会被放入版本库,也就是上图的master文件夹中 我们也可以偷看一下.git文件夹,需要注意的是,我们绝不能更改.git文件夹的任何内容 在整个git目录中,我们不需要全部搞明白,只需要抓住几个核心文件即可 objects:这是一个对象目录,存储的是git对象,Git进行版本管理的核心不是将文件全部备份,而是只记录修改的部分,当工作区代码修改后,会将修改的内容写入obj库中的一个新git对象中,因此暂存区和版本库存的不是数据本身,而是g...
557 words
死信队列的概念死信(Dead Letter)是消息队列中的一种特殊消息,是指没有办法被正常消费或者处理的消息,例如消息过期、消息被拒绝、队列满了 RabbitMQ的私信队列就专门用来存储这些死信消息 死信的来源 消息被拒绝(Rejection) 消费者显式拒绝接收某条消息,并且不希望该消息被重新投递时,这条消息会进入死信队列。 消息超时(TTL Expiration) 消息的生存时间(Time-To-Live, TTL)超过了指定的时长,而消息仍未被消费,这样的消息会被转移到死信队列。 队列长度超限(Queue Overflow) 当消息队列的长度达到最大限制,再有新消息进入时,多出来的消息可能会被直接移动到死信队列。 重试次数达到上限 某些消息在多次消费尝试失败(如因业务逻辑异常)后,达到最大重试次数后进入死信队列。 死信队列的应用场景对于RabbitMQ来说,死信队列是可以存储不能被正确消费的信息的,可以通过消费死信队列中的内容来分析可能出现的异常情况,可以用于改善和优化系统 可以用于比如说消息重试,丢弃,日志收集,人工处理等 常见的死信队列实现 RabbitMQ...
866 words
ProtoBuf介绍ProtoBuf全称是Protocol Buffer,是一个数据结构的序列化和反序列化框架 他又很多好处,首先是他支持跨平台,支持Java、C++、Python等多种语言,还比XML更小更快更简单 除此之外还可以更新数据结构,不会破坏原有的结构 使用流程 这个框架的使用流程是这样的 我们需要编写的是.proto文件,来描述结构化的对象,和其中的成员,属性 这个文件可以使用protoc编译器来处理,处理的结果就是我们需要的对应的语言,用来结构化对象数据操作的代码 我们在业务代码中包含这些头文件,就能使用这些方法把我们要序列化或者反序列化的数据进行处理 QUICK START这里我们通过一个简单的通讯录实现来快速上手protobuf 创建.proto文件推荐的规范 创建该文件,文件名必须用全小写命名,字母之间使用_连接 2字符缩进 注释与C/C++一样 12///* */ 语法123456789101112syntax = "proto3"; // 指定使用proto3版本语法package contacts; // 可选的声...
3.1k words
RPCRPC是一种通信协议 他可以让程序在不同的计算机上调用彼此的程序或者服务 就像本地调用函数一样调用远程服务器的服务 RPC框架负责底层的网络通信 序列化和反序列化数据 错误处理 这样我们在开发的过程中就不再需要重复造轮子了 这和reactor一样只是一种编程思想 各家公司一般都有自己的RPC框架 RPC架构和工作流程RPC的工作流程很简单 客户端调用:客户端调用本地的一个代理函数(stub),负责将请求参数序列化,然后发送到服务器 代理函数(stub):是负责客户端和服务器之间的通信 主要是为远程服务调用提供的一个本地接口 把远程调用的过程隐藏起来 他的内部处理功能就是序列化与反序列化 错误处理 返回结果 这种代理函数也支持多种编程语言 让不同语言的服务也能够通信 网络传输 服务处理:服务端接收代理函数的请求 反序列化参数 调用相关服务 响应返回 客户端接收 我们可以在很多地方都看到这种思想 例如MySQL的客户端和服务端分离 RabbitMQ的客户端服务端分离 客户端负责的起始就只有把请求按要求进行序列化和传递请求给服务端 真正运行复杂服务的是服务端 ...
474 words
在 C++ 项目中,灵活地读取用户配置是提升软件可用性的重要部分。本文将介绍几种常见的 C++ 配置库,包括它们的原理和使用方法。 1. inih 库原理inih 是一个轻量级的库,专门用于读取 .ini 格式的配置文件。它通过逐行解析文本文件,识别键值对和节(section),便于简单的配置管理。 使用方法 安装 inih 库: 1git clone https://github.com/benhung11/inih.git 创建配置文件(config.ini): 123[Settings]log_level=debugoutput_path=/var/log/myapp.log 代码示例: 123456789101112131415161718#include "INIReader.h"#include <iostream>int main() { INIReader reader("config.ini"); if (reader.ParseError() < 0) { ...
3k words
随着互联网技术的发展,业务规模和数据量不断扩大,为了能够又快又精确的为用户提供服务,技术架构也不断演进,来适应不同时期的业务需求 本文主要介绍八种业务架构以及优缺点和演进的过程 单机架构也称之为单体架构,主要指的是将系统的各个模块集成在一起形成一个整体的应用,通常是一整个服务器为用户提供服务 我们可以用一个简单的网站服务来画一个示意图 我们输入目标服务器的域名之后,会先访问DNS服务获取服务器的IP地址,然后在由服务器为用户提供服务,这里的网站服务和数据库服务是处于同一台机器的,因此也就是单机服务 特点:系统的各个模块集成在一起形成一个整体应用,通常由一个大型代码库管理 每次部署和更新都需要发布整个应用 优点:适合初期开发和快速上线,维护成本低,开发和测试相对简单 缺点:随着业务复杂度增加,单体架构的维护变得困难,更新和部署风险高,扩展性有限,容易出现性能瓶颈 相关软件Web 服务器软件:Tomcat、Netty、Nginx、Apache 等 数据库软件:MySQL、Oracle、PostgreSQL、SQL Server 等 应用数据分离架构当服务器的资源不够用的时候,一种很...